﻿Public Class Command
    Implements ICommand

    Private mExecute As Action(Of Object)
    Private mCanExecute As Func(Of Boolean)

    Public Sub New(Execute As Action(Of Object))
        mExecute = Execute
        mCanExecute = Nothing
    End Sub

    Public Sub New(Execute As Action(Of Object), CanExecute As Func(Of Boolean))
        mExecute = Execute
        mCanExecute = CanExecute
    End Sub

    Public Function CanExecute(parameter As Object) As Boolean Implements ICommand.CanExecute
        If mCanExecute IsNot Nothing Then
            Return mCanExecute.Invoke
        Else
            Return True
        End If
    End Function

    Public Event CanExecuteChanged(sender As Object, e As EventArgs) Implements ICommand.CanExecuteChanged

    Public Sub Execute(parameter As Object) Implements ICommand.Execute
        mExecute.Invoke(parameter)
    End Sub


    Private Shared mNotImplementedCommand As Command
    Public Shared ReadOnly Property NotImplementedCommand As Command
        Get
            If mNotImplementedCommand Is Nothing Then
                mNotImplementedCommand = New Command(Sub()
                                                         Throw New NotImplementedException()
                                                     End Sub, Function() False)
            End If
            Return mNotImplementedCommand
        End Get
    End Property

    Private Shared mSimpleCloseCommand As Command
    Public Shared ReadOnly Property SimpleClosedCommand As Command
        Get
            If mSimpleCloseCommand Is Nothing Then
                mSimpleCloseCommand = New Command(Sub(parameter As Object)
                                                      If parameter Is Nothing OrElse Not TypeOf parameter Is Window Then
                                                          Throw New ArgumentException("The CommandParameter for this command must be a reference to the window to close.")
                                                      Else
                                                          CType(parameter, Window).Close()
                                                      End If
                                                  End Sub)
            End If
            Return mSimpleCloseCommand
        End Get
    End Property
End Class
